package com.graduation_design.modules.app.controller;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.code.kaptcha.Producer;
import com.graduation_design.common.dto.LoginDto;
import com.graduation_design.common.dto.RegisterDto;
import com.graduation_design.common.lang.Result;
import com.graduation_design.entity.AppUser;
import com.graduation_design.service.AppUserService;
import com.graduation_design.utils.JwtUtils;
import com.graduation_design.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;

@Slf4j
@RestController
@RequestMapping("/app")
public class LoginController {

    @Resource
    AppUserService appUserService;

    @Resource
    JwtUtils jwtUtils;

    @Resource
    Producer producer;

    @Resource
    RedisUtil redisUtil;

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public Result login(@Validated @RequestBody LoginDto loginDto){

        // 校验用户名密码
        AppUser appUser = appUserService.login(loginDto);

        // 生成token
        String token = jwtUtils.generateToken(appUser.getId(), "APP");

        return Result.success(MapUtil.builder()
                .put("token", token)
                .put("userInfo", appUser)
                .build()
        );
    }

    /**
     * 图片验证码
     */
    @GetMapping("/captcha")
    public Result captcha() throws IOException {

        // 生成uuid和验证码
        String code = producer.createText();
        String uuid = UUID.randomUUID().toString();

        // 生成base64编码的图片验证码
        BufferedImage image = producer.createImage(code);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", outputStream);

        BASE64Encoder encoder = new BASE64Encoder();
        String base64Img = "data:image/jpeg;base64," + encoder.encode(outputStream.toByteArray());

        // 把uuid和验证码存储到redis缓存2分钟，方便后续验证验证码的正确性
        redisUtil.set(uuid, code, 120);

        log.info("验证码 - uuid - code -- {} - {}", uuid, code);

        // 返回uuid和base64图片
        return Result.success(MapUtil.builder()
                .put("uuid", uuid)
                .put("base64Img", base64Img)
                .build()
        );
    }

    /**
     * 用户注册
     */
    @PostMapping("/register")
    public Result register(@Validated @RequestBody RegisterDto form){

        // 验证码校验
        Assert.isTrue(form.getCode().equals(redisUtil.get(form.getUuid())), "验证码错误");

        // 判断用户名是否已存在
        long count = appUserService.count(new QueryWrapper<AppUser>().eq("username", form.getUsername()));
        if (count > 0){
            return Result.fail("用户名已存在");
        }

        // 进行注册
        AppUser user = new AppUser();
        user.setUsername(form.getUsername());
        user.setPassword(SecureUtil.md5(form.getPassword()));
        user.setCreated(LocalDateTime.now());
        appUserService.save(user);

        log.info("用户注册成功 ---- {}", user.getUsername());

        return Result.success();
    }

}
